package vsqlbuilder.gui.diagram;

import java.awt.Dimension;
import java.awt.Font;
import java.awt.FontMetrics;
import java.util.ArrayList;
import java.util.List;

import javax.swing.ImageIcon;

import vsqlbuilder.Utils;
import vsqlbuilder.logic.Column;
import vsqlbuilder.logic.Table;
import vsqlbuilder.logic.sql.Query;
import vsqlbuilder.logic.sql.QueryJoin;

public class DiagramModel {

	// contains list of all information objects to draw in the model.
	List<IGshape> elements;

	private int TablesNumber;
	private int JoinRelationsNumber;
	public DiagramView view;
	public DiagramController controller;
	public Query QueryStatment;
	private int Modelwidth;
	private int Modelheight;

	//
	// resource declarations for model
	public static final ImageIcon FIELD_IMAGE_ICON = Utils
			.getImageIcon("table/Field.gif");
	public static final ImageIcon NNFIELD_IMAGE_ICON = Utils
	.getImageIcon("table/NNField.gif");
	public static final ImageIcon TABLE_IMAGE_ICON = Utils
	.getImageIcon("table/Table.gif");
	public static final Font FONT = new Font("Arial", Font.PLAIN, 12);
	public final Font FONT2 = new Font("Dialog", Font.BOLD, 12);
	// TODO [low]: delete above line if not needed
	public FontMetrics FONT_METRICS; // TODO [low]: try to put in private visibility

	public DiagramModel(int width, int height) {
		// reset counters of objects
		TablesNumber = 0;
		JoinRelationsNumber=0;
		// set model dimensions
		Modelwidth = width;
		Modelheight = height;
		// Create Lists of objects
		this.elements = new ArrayList<IGshape>();
		this.controller = new DiagramController(elements);
		this.view = new DiagramView(new Dimension(Modelwidth, Modelheight),
				elements);
		this.QueryStatment = new Query();

		// Register Create Objects
		this.view.registerDiagramController(this.controller);
		this.view.registerModel(this);
		this.controller.registerView(this.view);
		this.controller.registerModel(this);
		this.controller.registerQuery(this.QueryStatment);

		// Register mouse & keyboard events of the diagram model
		this.controller.registerEvents(); // TODO [low]: this will be here or
											// in another place?
		// locate best position
		FONT_METRICS = null; // TODO [low]: research if this variable is used
								// later and if it's initialize somewhere.
	}

	// TODO [low]: this method can be easy move to DiagramController?
	public GTable addTable(int x, int y, Table t) {
		GTable drawShape = new GTable(x, y, t, FONT_METRICS);
		this.TablesNumber++;
		this.elements.add(drawShape);
		controller.addTableToQuery(t);
		view.repaint();
		return drawShape;
	}

	
	public GJoinRelation addJoin(GAnchorPoint source, GAnchorPoint destination, GTable ownerGTable, Column ownerColumn){
		JoinRelationsNumber++;
		//Create QueryJoin with diagram Info
		QueryJoin qj= new QueryJoin(source.getownerColumn(),destination.getownerColumn());
		GJoinRelation drawJoin=new GJoinRelation(source,destination,qj);
		ownerGTable.getAnchorPoint(ownerColumn).addJoinRelation(drawJoin);
		//Set initial calculations for anchors in join relation
		drawJoin.recalculateAnchors();
		controller.addJoinLinktoQuery(qj);
		view.repaint();
		return drawJoin;
	}
	
	
	//Check if the table name & schema owner name were used in diagram.
	public boolean isUsedTable(Table nt){
		boolean value=false;
		for(IGshape s : this.elements){
			if (s instanceof GTable){
				//GTable gt = (GTable)s;
				Table t = (Table)s.getShapeLogic();
				if (  (t.getName().equals(nt.getName())) &&  (t.getSchemaName().equals(nt.getSchemaName())) ){
					value=true;
				}
			}
		}
		return value;
	} 
	
	public void subtractionTable() {
		this.TablesNumber--;
	}
	
	public void subtractionJoinRelation() {
		this.JoinRelationsNumber--;
	}
	
	public int getModelWidth(){
		return this.Modelwidth;
	}
	
	public void clearModel(){
		this.elements.clear();
	}
	public int getModelHeight(){
		return this.Modelheight;
	}

}
